package com.sws.push.service.impl;

import com.alibaba.fastjson2.JSON;
import com.sws.common.annotation.Excel;
import com.sws.common.core.domain.R;
import com.sws.push.domain.*;

import com.sws.push.mapper.*;
import com.sws.push.service.AIAnalyzerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.List;

/**
 * AI分析服务实现类
 */
@Service
@Slf4j
public class AIAnalyzerServiceImpl implements AIAnalyzerService {

    private final ChatClient chatClient;
    
    @Autowired
    private RyProductMapper ryProductMapper;
    
    @Autowired
    private RyServiceMapper ryServiceMapper;
    
    @Autowired
    private RyConsumptionMapper ryConsumptionMapper;

    @Autowired
    private RyCustomerProfileMapper ryCustomerProfileMapper;

    private final BeanOutputConverter<RyCustomerProfile> converter;

    @Autowired
    private OpenAiChatModel baseChatModel;
    @Autowired
    private OpenAiApi baseOpenAiApi;
    @Autowired
    private AiModelConfigMapper aiModelConfigMapper;

    public AIAnalyzerServiceImpl(ChatClient.Builder chatClient) {
        RyCustomerProfile ryCustomerProfile = new RyCustomerProfile();
        String prejson = toPrettyJson(ryCustomerProfile);
        log.debug("AI分析器输出模板: {}", prejson);
        
        this.chatClient = chatClient
                .defaultSystem("""
                        format: 请严格按照outputExample格式，以json格式输出，请不要包含任何多余的文字和字符——包括 markdown 格式;
                        outputExample:
                        """ + prejson) // 方便后续转化为实体类
                .build();

        this.converter = new BeanOutputConverter<>(
                new ParameterizedTypeReference<>() {
                });
    }

    @Override
    public R analyze(Long customerId,String modelName) {
        log.info("开始分析客户: {}", customerId);
        
        // 设置查询参数
        RyProduct ryProduct = new RyProduct();
        ryProduct.setStatus(1L);// 上架状态

        RyService ryService = new RyService();
        ryService.setDelFlag(0L);// 未删除

        RyConsumption ryConsumption = new RyConsumption();
        ryConsumption.setCustomerId(customerId);
        ryConsumption.setDelFlag(0L);// 未删除

        // 查询数据
        log.debug("查询客户相关数据");
        java.util.List<RyProduct> ryProducts = ryProductMapper.selectAIRyProductList(ryProduct);
        java.util.List<RyService> ryServices = ryServiceMapper.selectRyServiceAIByServiceList(ryService);
        java.util.List<RyConsumption> ryConsumptions = ryConsumptionMapper.selectAIRyConsumptionList(ryConsumption);

        // 转换为JSON
        String ryProductsString = JSON.toJSONString(ryProducts);
        String ryServicesString = JSON.toJSONString(ryServices);
        String ryConsumptionsString = JSON.toJSONString(ryConsumptions);
        
        log.debug("数据转换完成: 产品数={}, 服务数={}, 消费记录数={}", 
                ryProducts.size(), ryServices.size(), ryConsumptions.size());

        // 查询数据库
        AiModelConfig aiModelConfig = new AiModelConfig();
        aiModelConfig.setModelName(modelName);
        List<AiModelConfig> aiModelConfigs = aiModelConfigMapper.selectAiModelConfigList(aiModelConfig);

        if (aiModelConfigs.isEmpty()) {
            throw new RuntimeException("为空");
        }
        AiModelConfig aiModelConfig1 = aiModelConfigs.get(0);

        //设置大模型参数
        OpenAiApi groqApi = baseOpenAiApi.mutate()
                .baseUrl(aiModelConfig1.getBaseUrl())
                .apiKey(aiModelConfig1.getApiKey())
                .build();
        OpenAiChatModel gpt4Model = baseChatModel.mutate()
                .openAiApi(groqApi)
                .defaultOptions(OpenAiChatOptions.builder().model(aiModelConfig1.getModel()).temperature(0.7).build())
                .build();

        RyCustomerProfile ryCustomerProfile = new RyCustomerProfile();
        String prejson = toPrettyJson(ryCustomerProfile);
        log.debug("AI分析器输出模板: {}", prejson);
        // 调用AI分析
        String content = ChatClient.builder(gpt4Model).defaultSystem("""
                        format: 请严格按照outputExample格式，以json格式输出，请不要包含任何多余的文字和字符——包括 markdown 格式;
                        outputExample:
                        """ + prejson).build().prompt()
                .user("requirement: 请根据以下数据，分析用户的消费习惯，喜欢的服务,并根据格式要求来输出;" +
                        "该用户的消费记录：" + ryConsumptionsString +
                        "产品列表：" + ryProductsString +
                        "服务列表：" + ryServicesString)
                .call().content();
                
        log.debug("AI生成内容: {}", content);
        
        // 转换响应并设置客户ID
        RyCustomerProfile convert = converter.convert(content);
        convert.setDelFlag(0L);
        convert.setCustomerId(customerId);

        // 检查是否存在客户画像
        RyCustomerProfile existingProfile = ryCustomerProfileMapper.selectByCustomerId(customerId);
        if (existingProfile != null) {
            // 存在则更新
            convert.setId(existingProfile.getId());
            ryCustomerProfileMapper.updateRyCustomerProfile(convert);
            log.info("客户画像已更新, 客户ID: {}", customerId);
        } else {
            // 不存在则插入
            ryCustomerProfileMapper.insertAIRyCustomerProfile(convert);
            log.info("客户画像已新建, 客户ID: {}", customerId);
        }

        return R.ok(convert);
    }

    /**
     * 将对象转换为格式良好的JSON
     */
    public static String toPrettyJson(Object obj) {
        if (obj == null)
            return "null";

        StringBuilder json = new StringBuilder();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        json.append("{\n");

        for (int i = 0; i < fields.length; i++) {
            try {
                fields[i].setAccessible(true);
                String fieldName = fields[i].getName();

                // 获取@Excel注解的注释内容
                Excel excelAnnotation = fields[i].getAnnotation(Excel.class);
                String comment = excelAnnotation != null ? " // " + excelAnnotation.name() : "";

                json.append("    \"").append(fieldName).append("\": {").append(fieldName).append("}").append(comment);

                if (i < fields.length - 1) {
                    json.append(",");
                }
                json.append("\n");
            } catch (Exception e) {
                // 忽略异常，继续处理其他字段
            }
        }

        json.append("}");
        return json.toString();
    }
}
